#version 460
#extension GL_GOOGLE_include_directive : enable
#extension GL_EXT_shader_explicit_arithmetic_types_int64 : require

#include "../../../../core/shader_binding_ID.h"
#include "../../../../core/shader_std.h"
#include "../../../../core/shader_built_in_functions.h"
#include "../../../../core/shader_taster_transform.h"
#include "../../../../core/shader_taster_color.h"
#include "../../../../core/shader_taster_line.h"
#include "../../../../core/shader_taster_bone.h"



layout(std140, set=0, binding=2) uniform U3_Matrix {
	vec4 mat_LightDir[4];	
};


layout(location = 0) in vec3 inPos;
layout(location = 1) in vec3 inNormal;
layout(location = 2) in vec2 inUV;


layout(location = 0) out vec4 vColor;
layout(location = 1) out vec3 vNormal;
layout(location = 2) out vec3 vLightPos[4];
layout(location = 6) out float vDepthScale;
layout(location = 8) out uint vPrimitiveID;
layout(location = 9) out uint vMeshOffset;
layout(location = 20) out uint vFaceOffset;

layout(location = DEF_BINDING_LocationBindID_Vert) out vec3 vVert;
layout(location = DEF_BINDING_LocationBindID_FaceAttr) out S_Geom_MeshDrawProp vFaceAttr;

layout(location = DEF_BINDING_LocationBindID_RotMat) out mat4 vTranformMat;
//layout(location = DEF_BINDING_LocationBindID_RotMat + 4) out mat4 vProjMat;
//layout(location = DEF_BINDING_TasterBindID_Origin) out vec3 origin

//layout(location = DEF_BINDING_TasterBindID_PrimitiveID) out uint vPrimitiveID;
//layout(location = 6) out flat uint vInstanceIndex;
out gl_PerVertex {
	vec4 gl_Position;
	float gl_PointSize;
};



void main(void){
	//uint InstanceIndex = gl_InstanceIndex + drawProp.MatrixOffset;
	//vInstanceIndex = gl_BaseInstance;
	mat4 bonesMat_som = mat_Model[gl_InstanceIndex + drawProp.MatrixOffset];
	vColor = f_glsl_buildColor(InstanceColor[gl_InstanceIndex + drawProp.ColorPropOffset]);
	//mat4 bonesMat_som = mat_Model[gl_InstanceIndex];
	//vColor = f_glsl_buildColor(InstanceColor[gl_InstanceIndex]);

	vTranformMat = bonesMat_som;
	vNormal = normalize(mat3x3(vTranformMat) * inNormal);

	//固定顶点坐标
	vec4 p = vec4(inPos, 1);
	S_MeshTranformProp prop = m_LinesProp[drawProp.MeshPropOffset + gl_DrawID];
	vVert = p.xyz;

	vDepthScale = prop.m_DepthScale;

	
	switch(drawProp.DrawType){
		case DEF_DrawType_LS:
			break;
		case DEF_DrawType_Weigth:
			vColor.x = 0;
			break;
		case DEF_DrawType_Normal_To_Col:
			vColor = vec4(inNormal, 1);
			break;
	}
	

	vec3 camPos = (inverse(mat_ProjecView[3]) * vec4(0,0,0,1)).xyz;

	if ( f_lineMeshTranform(p, inNormal, prop, bonesMat_som, (mat3(mat_ProjecView[1])), camPos) ) {
		gl_Position = mat_ProjecView[0] * p;
		return;
	}
	
	//p.xyz += vec3(prop.m_XMove, prop.m_YMove, prop.m_ZMove); inverse
	//if (prop.m_TransformMode < DEF_MESH_LINE_TRANFORMTYPEMODEL_PointLink) {
	//	p = bonesMat_som * p;
	//}
	
	
	
	vec3 a = p.xyz;
	vec3 n = vNormal;
	//float weigthColor = 0;
	if ( drawProp.BoneNum > 0) {
		uint VertexIndex = gl_VertexIndex - drawProp.VertexOffset;
		S_VertBone VertBone = m_VertBone[drawProp.BonesOffset + VertexIndex];
		//S_VertBone VertBone = m_VertBone[gl_VertexIndex];
		for (uint i=0; i<VertBone.num; ++i) {
			S_BoneMap BoneWeigth = m_BonesAttrOffset[VertBone.bone_offset + i + drawProp.BoneWeigetOffset];
			
			S_BonePose BonePose = m_SkeletonMatrix[BoneWeigth.boneID + drawProp.BonePoseOffset];

			//固定顶点到初始骨骼坐标
			vec3 p_pos = p.xyz - BonePose.tranformBoneA.xyz;

			p_pos = f_graph_quatTranformInv(BonePose.quat, p_pos) + BonePose.tranformBoneB.xyz;
			a = mix(a, p_pos, i > 0 ? BoneWeigth.weigth : 1);
			//a = mix(a, p_pos, BoneWeigth.weigth);
			//n = mix(n, newNormal, weigth);
			if(BonePose.select > 0){
				vColor.x = max(BoneWeigth.weigth, vColor.x);
			}
		}
	}
	p.xyz = a;
	vNormal = n;
	

	//vColor = f_glsl_buildColor(InstanceColor[gl_BaseInstance + drawProp.ColorPropOffset]);
	vFaceAttr.Offset_Face_AdjacencyID = drawProp.Offset_Face_AdjacencyID;
	vFaceAttr.Offset_Face_Normal = drawProp.Offset_Face_Normal;
	vFaceAttr.Offset_Face_Center = drawProp.Offset_Face_Center;
	vPrimitiveID = gl_VertexIndex;
	//vColor = vec4(0.5,0.5,0.5,1);
	vMeshOffset = drawProp.ObMesh_Offset;
	vFaceOffset = drawProp.ElementOffset;
	//vFaceOffset = 0;
	

	vLightPos[0] = normalize(inverse(mat3(mat_ProjecView[1])) * vec3(0.0, 0.0, DEF_ForwardDir));
	vLightPos[1] = (inverse(mat_ProjecView[3]) * vec4(0, 0, 0.1, 1)).xyz;
	//vLightPos[1] = normalize(vLightPos[0]);
	//vLightPos[2] = normalize(vec3(1.0, 1.0, 0.0));

	

	
	//vRotMat = mat_ProjecView[0];

	gl_Position = mat_ProjecView[0] * p;
	gl_PointSize = 1;
	
}


 





////蒙皮权重 [骨骼数量][骨骼内存偏移]
//layout(std430, column_major, binding = DEF_BINDING_Bones_Props) readonly buffer U7_VertexSkeleton {
//	uvec2 m_BonesProp[];
//};
//
//layout(std430, column_major, binding = DEF_BINDING_Bones_Weigth) readonly buffer U_VertexWeigth {
//	S_BonesWeigth m_ID_Weigth[];
//};
//
////骨骼对应变换
//layout(std430, column_major, binding = DEF_BINDING_Bones_Matrix) readonly buffer U_VertexSkeletonMatrix {
//	mat4 m_SkeletonMatrix[];
//};


	//mat4 bonesMat_A;
	//bonesMat_A[0] = vec4(1,0,0,0);
	//bonesMat_A[1] = vec4(0,1,0,0);
	//bonesMat_A[2] = vec4(0,0,1,0);
	//bonesMat_A[3] = vec4(0,0,0,1);
	//if(drawProp.BonesOffset > 0){
	//	uvec2 bonesID = m_BonesProp[gl_VertexIndex];
	//	
	//	for(uint i=0; i<bonesID.x; ++i){
	//		S_BonesWeigth id_weigth = m_ID_Weigth[bonesID.y + i];
	//		float weigth = id_weigth.Weigth;
	//			
	//		mat4 mat = m_SkeletonMatrix[id_weigth.BonesID];
	//		
	//		vec4 q = mat[1];
	//		//固定顶点到初始骨骼坐标
	//		vec3 p_pos = p.xyz - mat[3].xyz;
	//		//骨骼缩放顶点
	//		p_pos *= mat[0].xyz;
	//		//newPos.x = p.w * q.x + q.w * p.x + p.y * q.z - q.y * p.z;
	//		//newPos.y = p.w * q.y + q.w * p.y + p.z * q.x - q.z * p.x;
	//		//newPos.z = p.w * q.z + q.w * p.z + p.x * q.y - q.x * p.y;
	//		//newPos.w = q.w * q.w - q.x * q.x - q.y * q.y - q.z * q.z;
	//		//vec3 newPos = p_pos*(2.0f*q.w*q.w-1.0f) + cross(q.xyz, p_pos)*q.w*2.0f + (q.xyz)*dot((q.xyz), p_pos)*2.0f;
	//		vec3 newPos = p_pos*(2.0f*q.w*q.w-1.0f) - cross(q.xyz, p_pos)*q.w*2.0f + q.xyz*dot(q.xyz, p_pos)*2.0f;
	//		vec3 newNormal = vNormal*(2.0f*q.w*q.w-1.0f) - cross(q.xyz, vNormal)*q.w*2.0f + q.xyz*dot(q.xyz, vNormal)*2.0f;
	//		
	//		//旋转后的固定顶点加上变换后骨骼坐标
	//		newPos += mat[2].xyz;
	//		a.xyz = mix(a.xyz, newPos, weigth);
	//		n = mix(n, newNormal, weigth);
	//		//p.xyz = newPos;
	//		//break;
	//		
	//		if(i == 3){
	//			vColor = vec4(1,0,0, 1);
	//		}
	//		if(i == 4){
	//			vColor = vec4(0,1,0, 1);
	//		}
	//		if(i == 5){
	//			vColor = vec4(0,0,1, 1);
	//		}
	//		if(i == 6){
	//			vColor = vec4(1,1,0, 1);
	//			break;
	//		}
	//	}
	//}
	






 	
	//switch(prop.m_TransformMode){
	//	case DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD: {
	//		p *= mat_ProjecView[1];
	//		//p.xyz *= mat3(mat_ProjecView[1]);
	//		//p.xyz *= mat3(inverse(mat_ProjecView[0]));
	//		p.xyz += bonesMat_som[3].xyz;
	//		gl_Position = mat_ProjecView[0] * p;
	//		return;
	//	}
	//	case DEF_MESH_LINE_TRANFORMTYPEMODEL_VERTICAL: {
	//		p.xyz = vec3(0, -length(bonesMat_som * p), 0);
	//		break;
	//	}
	//	case DEF_MESH_LINE_TRANFORMTYPEMODEL_GAZE:{
	//		mat3 rot = mat3(mat_ProjecView[1]);
	//		vec3 H = (vec3(1, 0, 0) * rot);
	//		vec3 V = (vec3(0, 0, 1) * rot);
	//		vec3 dirLine = normalize(mat3(bonesMat_som) * vec3(0, 1, 0));
	//		vec3 right = normalize(mat3(bonesMat_som) * vec3(1, 0, 0));
	//		H = normalize(cross(dirLine, V));
	//		
	//		p.xyz = H*p.x + V*p.z + dirLine*p.y;
	//		p.xyz += bonesMat_som[3].xyz;
//
	//		gl_Position = mat_ProjecView[0] * p;
	//		return;
	//	}
	//	case DEF_MESH_LINE_TRANFORMTYPEMODEL_CenterZoom : {
	//		p.x *= prop.m_XScale;
	//		p.y *= prop.m_YScale;
	//		p.z *= prop.m_ZScale;
	//		break;
	//	}
	//	case DEF_MESH_LINE_TRANFORMTYPEMODEL_ZAxialZoom : {
	//		p.x *= prop.m_XScale;
	//		p.y *= prop.m_YScale;
	//		p.z *= prop.m_ZScale;
	//		break;
	//	}
	//	case DEF_MESH_LINE_TRANFORMTYPEMODEL_CAMERAGAZE : {
	//		p.xyz *= mat3(mat_ProjecView[1]);
	//		break;
	//	}
	//	case DEF_MESH_LINE_TRANFORMTYPEMODEL_PointLink : {
	//		f_lineMeshTranform(p, prop, bonesMat_som, mat3(mat_ProjecView[1]), DEF_MESH_LINE_TRANFORMTYPEMODEL_PointLink);
	//		break;
	//	}
	//	default:{
	//		break;
	//	}
	//}











